﻿using System;
using System.Data;
using System.Windows.Forms;
using SdmxMl.Common;
using SdmxMl.Manager;

namespace SdmxMl.Panels
{
    /// <summary>
    /// Dialog Box for view and submit on change notification service
    /// </summary>
    public partial class DlgSubscribe : Form
    {
        #region Internal members

        private DataTable tbSubscription;
        private Subscription.Subscription sub;
        private string winUser;
        private static string AnyMarker = "All";
        private static int TYPE_NDX = 1;

        #endregion

        #region C'tor

        public DlgSubscribe(string subscriptionUrl)
        {
            InitializeComponent();

            // Fetch window user from TinyRegistry info
            winUser = SdmxMl.Multiplexor.Mux.Instance.UserId;

            // Instantiate subecription service 
            sub = new SdmxMl.Subscription.Subscription();
            sub.Url = subscriptionUrl;

            // Fetch current user subscriptions in grid
            tbSubscription = sub.getUserSubscriptions(winUser);
            dataGridViewSub.DataSource = tbSubscription;

            if (tbSubscription != null)
            {
                // Registered mail
                textBoxMail.Text = tbSubscription.ExtendedProperties["Mail"].ToString();

                // Retrieve period
                TimeSpan ts = TimeSpan.Parse(tbSubscription.ExtendedProperties["Period"].ToString());
                numericUpDownPeriod.Value = ts.Days;

                // Rows presentation
                UpdatePresentationTable(true);
            }

            //Fetch mail from MUX (if exists)
            if (textBoxMail.Text.Length == 0)
            {
                textBoxMail.Text = Multiplexor.Mux.Instance.GetMailOfUser(winUser);
            }


            // Set edition buttons status
            UpdateButtons();
        }
        #endregion

        #region Url Button Event

        /// <summary>Add according to Artefact URL (previously copied)</summary>
        /// <param name="sender"></param> <param name="e"></param>
        private void buttonAddUrl_Click(object sender, EventArgs e)
        {
            UrnParser p = new UrnParser(ReferenceManager.ArTypedCopyInstanceUrn);
            if (p.IsSupported)
            {
                tbSubscription.Rows.Add(new object[] { p.AgencyId, p.TypedReference.Type.ToString(), p.ArtefactId, p.Version, AnyMarker });
                UpdateButtons();
            }
        }

        #endregion

        #region Update subscription Event

        private void buttonSubmit_Click(object sender, EventArgs e)
        {
            UpdatePresentationTable(false);
            bool stateOk = sub.updateUserSubscriptions(winUser, tbSubscription);
            UpdatePresentationTable(true);

            // Period
            TimeSpan ts = new TimeSpan((int) numericUpDownPeriod.Value, 0, 0, 0);
            if (stateOk)
                stateOk = sub.updateUserNotificationPeriod(winUser, ts.ToString());

            // Mail Addr
            if (stateOk)
                stateOk = sub.updateUserMailAddress(winUser, textBoxMail.Text.Trim());

            if (stateOk == false)
            {
                MessageBox.Show(this, "Subscription error signalled by service!", "Subscribe", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
                this.Close();
        }
        #endregion

        #region Table Presentation

        private void UpdatePresentationTable(bool toScreen)
        {
            if (toScreen)
            {
                foreach (DataRow row in tbSubscription.Rows)
                {
                    for (int i = 0; i < tbSubscription.Columns.Count; ++i)
                    {
                        string s = row[i].ToString();
                        s = s.Replace("\\A", "");
                        s = s.Replace("\\z", "");
                        if (s == ".*")
                            s = AnyMarker;
                        else if (i == TYPE_NDX)
                        {
                            foreach (SdmxArtefactType atype in Enum.GetValues(typeof(SdmxArtefactType)))
                            {
                                if (atype.ToString().ToLower() == s)
                                {
                                    s = atype.ToString();
                                    break;
                                }
                            }

                        }
                        row[i] = s;
                    }
                }
            }
            else
            {
                foreach (DataRow row in tbSubscription.Rows)
                {
                    for (int i = 0; i < tbSubscription.Columns.Count; ++i)
                    {
                        string s = row[i].ToString();
                        if (s == AnyMarker)
                            s = ".*";
                        else
                        {
                            s = "\\A" + ((i == TYPE_NDX) ? s.ToLower() : s) + "\\z";
                        }
                        row[i] = s;
                    }
                }
            }
        }
        

        #endregion

        #region Grid editon buttons event

        private void UpdateButtons()
        {
            butRemove.Enabled = butEdit.Enabled = tbSubscription != null && tbSubscription.Rows.Count > 0;
            buttonAddUrl.Enabled = butAdd.Enabled = tbSubscription != null;
        }

        private DataRow FindSelectedRow()
        {
            DataRow findRow = null;
            if (dataGridViewSub.DataSource != null && dataGridViewSub.CurrentRow != null)
            {
                DataRowView drv = dataGridViewSub.CurrentRow.DataBoundItem as DataRowView;
                if (drv != null)
                    findRow = drv.Row;
            }

            return findRow;
        }


        private void butAdd_Click(object sender, EventArgs e)
        {
            DlgSubscribeItem aDlg = new DlgSubscribeItem(null);
            if (aDlg.ShowDialog() == DialogResult.OK)
            {
                tbSubscription.Rows.Add(aDlg.artefactsSelector.SelectionArray);
                UpdateButtons();
            }
        }

        private void butRemove_Click(object sender, EventArgs e)
        {
            DataRow findRow = FindSelectedRow();
            if (findRow != null)
                tbSubscription.Rows.Remove(findRow);
            UpdateButtons();
        }

        private void butEdit_Click(object sender, EventArgs e)
        {
            DataRow findRow = FindSelectedRow();
            if (findRow != null)
            {
                DlgSubscribeItem aDlg = new DlgSubscribeItem(findRow);
                if (aDlg.ShowDialog() == DialogResult.OK)
                {
                    findRow.ItemArray = aDlg.artefactsSelector.SelectionArray;
                }
            }
        }
        #endregion

        #region Cancel Event

        private void buttonCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        #endregion

    }
}
